Neste tutorial iremos apresentar as implementações dos algoritmos de Árvores de Classificação e Regressão que podem também ser chamados de CART. Este é um poderoso método de predição bastante popular. A árvore de decisão final explica exatamente o porquê de uma predição específica ter sido feita, tornando-a muito atrativa para o uso. Elas também servem de base para métodos mais avançados. Para implementar a árvore iremos utilizar funções das bibliotecas do Scikit-learn, do Pandas e do Numpy.
São algoritmos que podem ser utilizados para problemas de modelagem preditiva classificativa ou regressiva. Vamos focar no uso do modelo CART(Árvores de Classificação e Regressão) para classificação nesse tutorial. A representação do método é uma árvore binária. Um nó representa uma única variável de entrada (X) e um ponto de divisão nessa variável, assumindo que é numérica. Os nós folhas (também chamados de nós terminais) de uma árvore contém uma variável de saída (Y) a qual é utilizada para fazer uma predição. Uma vez criada, uma árvore pode ser navegada com uma nova linha de dados seguindo cada ramo com as divisões até a última predição ser feita.
Utilizaremos o conjunto de dados denominado BankNote Dataset disponível nesse link: https://goo.gl/rLPrHO. Esse dataset é utilizado para prever se uma cédula é autêntica dado o conjunto de medidas tiradas de uma fotografia. Esse problema é composto por 1372 observações de dados que foram extraídos de imagens que foram tiradas de cédulas genuínas e falsas. Foi utilizada uma ferramenta de transformação "wavelet"(função capaz de decompor e descrever ou representar outra função) para extrair essas informações da imagem. Os registros mostram a variância, a obliquidade e a curtose(é uma medida de forma que caracteriza o achatamento da curva da função) da imagem transformada pela ferramenta, além disso há a entropia da imagem. Cada registro há um valor de classe que indica se a cédula é autentica (0) ou não (1).
Nesta etapa vamos utilizar a biblioteca Pandas. O Pandas é uma biblioteca do python que oferece suporte para operações de manipulação e análise de dados.
O primeiro passo é importar o pandas. Para ler o arquivo .csv que contém o dataset iremos utilizar a função read_csv. O primeiro parâmetro que passamos é o nome do arquivo que desejamos ler. Ao fazermos a atribuição "header= None" estamos informando a função que o nosso dataset não possui cabeçalho. O dataset será então retornamos como um DataFrame que será armazenado na variável data.
In [1]:
import pandas as pd
data = pd.read_csv('banknote.csv', header= None)
Utilizaremos a função head() para visualizar as primeiras linhas do dataframe.
In [3]:
data.head()
Out[3]:
Se desejar visualizar todo o dataset executa a seguinte linha de código.
In [2]:
data
Out[2]:
In [3]:
data.info()
Iremos agora utilizar a função iloc do pandas para dividir o nosso dataset. Em X iremos guardar os valores da coluna 0 até a coluna 3 do dataset, em Y iremos guardar os valores da última coluna, que correspondem aos valores de saída.
In [10]:
X = data.iloc[:,[0,1,2,3]]
Y = data.iloc[:,4]
O próximo passo é dividir o conjunto de dados, em dados de treino e de teste. Para isso usaremos a função train_test_split da biblioteca sklearn.
In [11]:
from sklearn.model_selection import train_test_split
Dividiremos os dados da seguinte forma: 80% dos dados serão utilizados para treino e 20% para teste. Os dados de treino serão então separados e guardados em duas variáveis: o X_train guarda os valores da coluna 0 até a 4 e o y_train guarda os valores de saída correspondente a cada linha do X_train. A divisão acontecerá da mesma forma entre o X_test e o y_test para os dados de treino.
In [12]:
X_train, X_test, y_train, y_test = train_test_split(X, Y, train_size=0.8, test_size= 0.2, random_state=1)
In [13]:
from sklearn.tree import DecisionTreeClassifier
Vamos utilizar a função DecisionTreeClassifier para modelar. O parâmetro criterion define a função utilizada para medir a qualidade da divisão. No nosso caso definimos o critério com 'gini'.
O coeficiente é uma função de custo utilizada para avaliar divisões no dataset. Uma divisão neste envolve um atributo de entrada e um valor para este atributo. Uma separação perfeita resulta em um valor de Gini igual a 0, no pior caso, ou seja, no caso em que a separação resulta em 50/50, resulta em um valor de Gini igual a 0.5.
O parâmetro max_depth define a máxima profundidade de uma árvore: Isso é o número máximo de nós da raiz da árvore. Uma vez que a profundidade máxima é atingida devemos parar de adicionar novos nós. Árvores muito profundas são mais complexas e mais prováveis de superar os dados de treinamento.
O parâmetro min_samples_split define o número mínimo de registros nos nós: É o número mínimo de padrões de treinamento que um nó é responsável. Uma vez menor ou igual que o mínimo, devemos parar de dividir e adicionar novos nós. Nós que são responsaveis por poucos padrões de treinamento são muitos específicos.
Esta função aceita ainda outros parâmetros, mas para o nosso caso estes são suficientes.
In [14]:
model = DecisionTreeClassifier(criterion='gini', max_depth= 5, min_samples_split= 10)
Agora iremos treinar o nosso modelo, utilizando a função fit do sklearn, usaremos os conjuntos de dados de treino que tínhamos preparados anteriormente.
In [15]:
model.fit(X_train, y_train)
Out[15]:
Vamos agora utilizar o nosso modelo para efetuar uma predição sobre o nosso dataset. Usaremos a função predict do sklearn e o nosso conjunto de dados X_test.
In [16]:
predicao = model.predict(X_test)
In [17]:
predicao
Out[17]:
É natural querermos saber quão bom é o desempenho do modelo que desenvolvemos sobre o dataset. Para calcular a acurácia podemos utilizar a função score do sklearn.tree.
In [28]:
accuracy = model.score(X_test, y_test)*100
In [31]:
print('Accuracy: %s%%' % accuracy)
Podemos também usar o método da validação cruzada com k-fold para avaliar o nosso algoritmo. Iremos utilizar as funções KFold e cross_val_score, ambas terão de ser importadas da biblioteca sklearn.model_selection.
In [35]:
from sklearn.model_selection import KFold, cross_val_score
import numpy as np
Utilizaremos 5 folds.
In [36]:
k_fold = KFold(n_splits=5)
In [37]:
scores = cross_val_score(model, X, Y, cv=k_fold, n_jobs=-1)
Podemos então ver o desempenho do algoritmo quando avaliado sobre cada um dos folds.
In [38]:
scores
Out[38]:
Por fim podemos calcular a média dos scores utilizando a função mean da biblioteca numpy, que já foi importada acima.
In [41]:
media = np.mean(scores) * 100
In [42]:
print('Media: %s%%' % media)